(* DONT_TOUCH = "TRUE" *)
module pcl7152_init_ctrl_auto #(
    parameter WR_WAIT_TIME   = 14'd5000,
    parameter INIT_DELAY     = 16'd100000 
)(
    input clk,
    input rst_n,
    output reg init_done,

    output reg i2c_exec,
    output reg bit_ctrl,
    output reg i2c_rh_wl,
    output reg [7:0] i2c_addr,
    output reg [7:0] i2c_data_w,
    input i2c_done,
    input i2c_ack,

    //test
    output reg [5:0] index,
    output reg [2:0] state
);

reg [15:0] cfg_data [0:31];
initial begin
    cfg_data[0] = {8'h02, 8'h1F};
    cfg_data[1] = {8'h03, 8'h00};

    cfg_data[2] = {8'h06, 8'h00};
    cfg_data[3] = {8'h07, 8'h00};

    cfg_data[4] = {8'h18, 8'h02}; 
    cfg_data[5] = {8'h19, 8'h00};

    cfg_data[6] = {8'h7C, 8'h06};
    cfg_data[7] = {8'h7D, 8'h00};

    cfg_data[8] = {8'h12, 8'h03};
    cfg_data[9] = {8'h13, 8'h00};

    cfg_data[10] = {8'h14, 8'h01}; 
    cfg_data[11] = {8'h04, 8'h02};
    cfg_data[12] = {8'h05, 8'h00};

    cfg_data[13] = {8'h4E, 8'h00};
    cfg_data[14] = {8'h4F, 8'h0C}; 

    cfg_data[15] = {8'h7A, 8'h41};
    cfg_data[16] = {8'h7B, 8'h03}; 

    cfg_data[17] = {8'h68, 8'h79};
    cfg_data[18] = {8'h69, 8'h02};

    cfg_data[19] = {8'h6A, 8'h24};
    cfg_data[20] = {8'h6B, 8'h02};

    cfg_data[21] = {8'h0E, 8'hE2}; 
    cfg_data[22] = {8'h0F, 8'h04}; 
    cfg_data[23] = {8'h10, 8'h88}; 
    cfg_data[24] = {8'h11, 8'h13}; 

    cfg_data[25] = {8'h12, 8'h03};
    cfg_data[26] = {8'h13, 8'h00};

    cfg_data[27] = {8'h04, 8'h02};
    cfg_data[28] = {8'h05, 8'h00};

    cfg_data[29] = {8'h12, 8'h01};
    cfg_data[30] = {8'h13, 8'h00};

end

// 状态机定义
reg [2:0] state;
localparam DELAY = 3'd0, IDLE = 3'd1, EXEC = 3'd2, WAIT_DONE = 3'd3, WAIT_INTERVAL = 3'd4;

reg [15:0] delay_cnt;
reg [13:0] wait_cnt;
reg [5:0]  index;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        i2c_exec    <= 0;
        i2c_rh_wl   <= 0;
        bit_ctrl    <= 0;
        i2c_addr    <= 0;
        i2c_data_w  <= 0;
        index       <= 0;
        wait_cnt    <= 0;
        delay_cnt   <= 0;
        init_done   <= 0;
        state       <= DELAY;
    end else begin
        case (state)
            DELAY: begin
                if (delay_cnt < INIT_DELAY - 1) begin
                    delay_cnt <= delay_cnt + 1;
                end else begin
                    state <= IDLE;
                end
            end

            IDLE: begin
                if (index < 31) begin
                    i2c_addr   <= cfg_data[index][15:8];
                    i2c_data_w <= cfg_data[index][7:0];
                    i2c_rh_wl  <= 0;
                    i2c_exec   <= 1;
                    state      <= EXEC;
                end else begin
                    init_done <= 1;
                    state <= IDLE;
                end
            end

            EXEC: begin
                i2c_exec <= 0;
                state <= WAIT_DONE;
            end

            WAIT_DONE: begin
                if (i2c_done) begin
                    if (!i2c_ack) begin
                        index <= index + 1;
                        wait_cnt <= 0;
                        state <= WAIT_INTERVAL;
                    end else begin
                        init_done <= 1;
                        state <= IDLE;
                    end
                end
            end

            WAIT_INTERVAL: begin
                wait_cnt <= wait_cnt + 1;
                if (wait_cnt == WR_WAIT_TIME - 1) begin
                    state <= IDLE;
                end
            end

            default: state <= DELAY;
        endcase
    end
end

endmodule
